from __future__ import annotations

import json
from dataclasses import dataclass, asdict
from datetime import datetime, timezone
from pathlib import Path
from typing import Dict, List, Optional

from .paths import get_accounts_path


@dataclass
class Account:
    id: str
    display_name: str
    type: str  # 'human' | 'agent'
    created_at: str


@dataclass
class AccountsStore:
    accounts: Dict[str, Account]
    default_owner: str
    default_actor: str

    @classmethod
    def default(cls) -> "AccountsStore":
        now = datetime.now(timezone.utc).isoformat()
        base = {
            "me": Account(id="me", display_name="Me", type="human", created_at=now),
            "claude": Account(id="claude", display_name="Claude", type="agent", created_at=now),
            "codex": Account(id="codex", display_name="Codex", type="agent", created_at=now),
        }
        return cls(accounts=base, default_owner="me", default_actor="me")

    def to_json(self) -> dict:
        return {
            "accounts": {k: asdict(v) for k, v in self.accounts.items()},
            "default_owner": self.default_owner,
            "default_actor": self.default_actor,
        }

    @classmethod
    def from_json(cls, data: dict) -> "AccountsStore":
        accs = {k: Account(**v) for k, v in data.get("accounts", {}).items()}
        return cls(
            accounts=accs,
            default_owner=data.get("default_owner", "me"),
            default_actor=data.get("default_actor", "me"),
        )


def load_accounts() -> AccountsStore:
    path = get_accounts_path()
    if not path.exists():
        store = AccountsStore.default()
        save_accounts(store)
        return store
    data = json.loads(path.read_text(encoding="utf-8"))
    return AccountsStore.from_json(data)


def save_accounts(store: AccountsStore) -> None:
    path = get_accounts_path()
    path.write_text(json.dumps(store.to_json(), ensure_ascii=False, indent=2), encoding="utf-8")


def add_account(acc_id: str, display_name: str, acc_type: str) -> None:
    store = load_accounts()
    if acc_id in store.accounts:
        raise SystemExit(f"Account '{acc_id}' already exists")
    now = datetime.now(timezone.utc).isoformat()
    store.accounts[acc_id] = Account(
        id=acc_id, display_name=display_name or acc_id, type=acc_type, created_at=now
    )
    save_accounts(store)


def list_accounts() -> List[Account]:
    return list(load_accounts().accounts.values())


def set_default(owner: Optional[str] = None, actor: Optional[str] = None) -> None:
    store = load_accounts()
    if owner is not None:
        if owner not in store.accounts:
            raise SystemExit(f"Owner '{owner}' not found")
        store.default_owner = owner
    if actor is not None:
        if actor not in store.accounts:
            raise SystemExit(f"Actor '{actor}' not found")
        store.default_actor = actor
    save_accounts(store)

